package edu.pku.sei.mte.transformation.qvt;

import java.util.ArrayList;
import java.util.List;

import edu.pku.sei.mte.mtemodel.model.MModelGraph;
import edu.pku.sei.mte.mtemodel.mtmodel.rulebased.RBTransformation;
import edu.pku.sei.mte.mtemodel.mtmodel.rulebased.Relation;
import edu.pku.sei.mte.mtemodel.mtmodel.rulebased.Rule;
import edu.pku.sei.mte.runtime.Context;
import edu.pku.sei.mte.runtime.rulebased.RBTContext;
import edu.pku.sei.mte.runtime.rulebased.RBTEnvironment;

public class QVTEnforceVisitor extends QVTSemanticVisitor {
	
	public QVTEnforceVisitor(RBTEnvironment env) {
		super(env);
	}

	@Override
	public Object visitRBTransformation(RBTransformation e) throws Exception {
		MModelGraph targetModel = this.getEnv().getModelGraph(getEnv().getTarget());
		do {
			targetModel.resetChangeState();
			for(Rule r : e.getTopLevelRules()){
				RBTContext c = getEnv().createNewContext();
				r.registVariableToContext(c);
				getContextStack().push(c);
				System.out.println("Enforce Rule "+r.getName());
				if(r.accept(this) != Boolean.TRUE){
					System.out.println("Rule " + r.getName() + " failed");
					return Boolean.FALSE;
				}
				System.out.println("Rule " + r.getName() + " passed");
				getContextStack().pop();
			}
		}while(targetModel.isGraphChange());
		return Boolean.TRUE;
	}
	
	@Override
	public Object visitRelation(Relation e) throws Exception {
		List<Context> unsatisfied = new ArrayList<Context>();
		getSemantic().findContext(e, getContextStack().peek(), null, unsatisfied, false);
		getSemantic().qvtCreateRelation(e, getEnv(), unsatisfied);
		getSemantic().qvtDeleteRelation(e, getEnv(), getContextStack().peek());
		return true;
	}
	
}
